import socket
import struct
import binascii
import time
import os
from time import sleep

# from helloserver import wrap_handshake

def wrap_handshake(handshake_data):
    record_type = b'\x16'
    protocol_version = b'\x03\x03'
    record_length = struct.pack('>H', len(handshake_data))
    return record_type + protocol_version + record_length + handshake_data

def create_client_hello():
    # TLS协议版本（TLS 1.2）
    version = b'\x03\x03'

    # 随机数（前4字节为时间戳，后28字节为随机数）
    timestamp = struct.pack('>I', int(time.time()))
    random_bytes = os.urandom(28)
    random = timestamp + random_bytes

    # 会话ID（空）
    session_id_len = b'\x00'
    session_id = b''

    # 密码套件列表（ECDHE-RSA-AES256-GCM-SHA384）
    cipher_suites = [0xc030]  # TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    cipher_suites_bytes = b''.join(struct.pack('>H', suite) for suite in cipher_suites)
    cipher_suites_len = struct.pack('>H', len(cipher_suites_bytes))

    # 压缩方法（空）
    compression_methods = [0x00]
    compression_methods_bytes = bytes(compression_methods)
    compression_methods_len = struct.pack('B', len(compression_methods_bytes))

    # 扩展（支持SNI和ALPN）
    extensions = []

    # SNI扩展（可选）
    server_name = b'localhost'
    sni_data = (
            struct.pack('>H', 0x0000) +  # 类型：server_name
            struct.pack('>H', len(server_name) + 3) +  # 长度
            struct.pack('>B', 0) +  # 名称类型：host_name
            struct.pack('>H', len(server_name)) +  # 名称长度
            server_name
    )
    extensions.append(sni_data)

    # ALPN扩展（可选）
    alpn_protocols = [b'h2', b'http/1.1']
    alpn_data = (
            struct.pack('>H', 0x0010) +  # 类型：application_layer_protocol_negotiation
            struct.pack('>H', len(alpn_protocols) + 1) +  # 长度
            b''.join(struct.pack('B', len(p)) + p for p in alpn_protocols)
    )
    extensions.append(alpn_data)

    # 椭圆曲线扩展（可选）
    curves = [0x001D, 0x0017, 0x0018]  # secp256r1, secp384r1, secp521r1
    curves_bytes = (
            struct.pack('>H', len(curves) * 2) +  # 曲线列表长度
            b''.join(struct.pack('>H', curve) for curve in curves)
    )
    extensions.append(
        struct.pack('>H', 0x000a) +  # 类型：supported_groups
        struct.pack('>H', len(curves_bytes)) +  # 长度
        curves_bytes
    )

    # 构建扩展部分
    extensions_bytes = b''.join(extensions)
    extensions_len = struct.pack('>H', len(extensions_bytes))

    # 组合ClientHello消息
    client_hello = (
            b'\x01' +  # 消息类型：ClientHello
            struct.pack('>I', len(version) + len(random) + len(session_id_len) + len(session_id) +
                        len(cipher_suites_len) + len(cipher_suites_bytes) +
                        len(compression_methods_len) + len(compression_methods_bytes) +
                        len(extensions_len) + len(extensions_bytes))[1:] +  # 消息长度（3字节）
            version +
            random +
            session_id_len +
            session_id +
            cipher_suites_len +
            cipher_suites_bytes +
            compression_methods_len +
            compression_methods_bytes +
            extensions_len +
            extensions_bytes
    )

    return client_hello


# 发送ClientHello报文
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 8443))

client_hello = create_client_hello()
print("发送ClientHello报文：")
print(binascii.hexlify(client_hello).decode())

s.sendall(wrap_handshake(client_hello))
sleep(10)
# 接收服务器响应（示例代码）
response = s.recv(4096)
print("\n收到服务器响应：")
print(binascii.hexlify(response).decode())

s.close()